import { Sequelize, Op } from 'sequelize';
import config from 'config';
import Logger from './logger.js';
const logger = Logger.getLogger('DB');

class Database {
  constructor() {
    this.sequelize = null;
    this.isInitialized = false;
  }

  async init() {
    if (this.isInitialized) {
      return this.sequelize;
    }

    try {
      const sequelize = new Sequelize({
        logging: (sql) => {
          if (config.get('mysql.logger')) {
            logger.info(`${sql}`);
          }
        },
        host: config.get('mysql.host'),
        port: config.get('mysql.port'),
        database: config.get('mysql.database'),
        username: config.get('mysql.username'),
        password: config.get('mysql.password'),
        dialect: 'mysql',
        pool: {
          max: 10,
          min: 0,
          acquire: 30000,
          idle: 10000
        },
        retry: {
          max: 3
        }
      });

      // Note: setOperatorsAliases is deprecated in newer Sequelize versions
      // The operators are now available directly through the Op object

      await sequelize.authenticate();
      logger.info('Database connection established successfully');

      this.sequelize = sequelize;
      this.isInitialized = true;

      return sequelize;
    } catch (error) {
      logger.error('Database connection failed:', error);
      throw error;
    }
  }

  async defineModel(define) {
    if (!this.isInitialized) {
      await this.init();
    }

    try {
      const Model = await define(this.sequelize, Sequelize);
      await Model.sync();
      return Model;
    } catch (error) {
      logger.error('Model definition failed:', error);
      throw error;
    }
  }

  async close() {
    if (this.sequelize) {
      await this.sequelize.close();
      this.isInitialized = false;
      logger.info('Database connection closed');
    }
  }

  getSequelize() {
    if (!this.isInitialized) {
      throw new Error('Database not initialized. Call init() first.');
    }
    return this.sequelize;
  }
}

// Singleton instance
const DB = new Database();

export default DB;
